package com.mhkj.revise.plan.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.mhkj.base.busiType.service.BusinessTypeService;
import com.mhkj.base.templete.service.PlanTempleteService;
import com.mhkj.common.enums.PlanType;
import com.mhkj.common.util.ItemHelper;
import com.mhkj.revise.plan.entity.Plan;
import com.mhkj.revise.plan.entity.PlanNode;
import com.mhkj.revise.plan.repository.PlanRepository;
import com.mhkj.revise.plan.service.PlanNodeService;
import com.mhkj.revise.plan.service.PlanService;
import com.mics.core.common.componet.Pagination;
import com.mics.core.system.base.service.impl.BaseServiceImpl;
import com.mics.core.system.organizational.service.OrgService;
import com.mics.core.system.rbac.service.DictionaryService;

/**
 * 计划服务
 * @author mics
 * @date 2018年7月5日
 * @version 1.0
 */
@Service
public class PlanServiceImpl extends BaseServiceImpl<Plan> implements PlanService{
	@Resource
	private PlanRepository planRepository;
	@Resource
	private OrgService orgService;
	@Resource
	private PlanTempleteService planTempleteService;
	@Resource
	private PlanNodeService planNodeService;
	@Resource
	private DictionaryService dictionaryService;
	@Resource
	private BusinessTypeService businessTypeService;
	@Resource
	private PlanService planService;
	@Resource
	private ItemHelper itemHelper;
	
	
	@Resource
	public void setPlanRepository(PlanRepository planRepository) {
		super.setBaseRepository(planRepository);
	}

	@Override
	public Pagination<Plan> listByPage(Plan plan, int pageIndex, int pageSize) {
		Specification<Plan> spec = new Specification<Plan> () {  
			/**
			 * 序列号
			 */
			private static final long serialVersionUID = -786003485941679959L;
			@Override
			public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
              List<Predicate> lstPredicates = new ArrayList<Predicate>();
              if(!StringUtils.isEmpty(plan.getName())){
                  Predicate p1=criteriaBuilder.like(root.get("name").as(String.class), "%"+plan.getName()+"%");
                  lstPredicates.add(p1);
              }
              if(plan.getPlanType() != null){
                  Join<Object, Object> planType = root.join("planType",JoinType.INNER);
                  Predicate p1=criteriaBuilder.equal(planType.get("id").as(Long.class), plan.getPlanType().getId());
                  lstPredicates.add(p1);
              }
              if(plan.getState() == 0){
                  Predicate p1=criteriaBuilder.notEqual(root.get("state").as(Integer.class),0);
                  lstPredicates.add(p1);
              }else {
                  Predicate p1=criteriaBuilder.equal(root.get("state").as(Integer.class),0);
                  lstPredicates.add(p1);
              }
              Predicate[] arrayPredicates = new Predicate[lstPredicates.size() ];
              return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
	        }
		};
		Page<Plan> pageT =  planRepository.findAll(spec, PageRequest.of(pageIndex, pageSize, Sort.Direction.ASC,"id"));
		Pagination<Plan> pagination = new Pagination<Plan>();
		pagination.setTotal(planRepository.count(spec));
		List<Plan> Plans = pageT.getContent();
		pagination.setData(Plans);
		return pagination;
	}

	@Override
	public List<Plan> findPlanByItemId(Long itemId, Long planTypeId,String code) {
		Specification<Plan> spec = new Specification<Plan> () {  
			/**
			 * 序列号
			 */
			private static final long serialVersionUID = -786003485941679959L;
			@Override
			public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
              List<Predicate> lstPredicates = new ArrayList<Predicate>();
              Predicate[] arrayPredicates = new Predicate[lstPredicates.size() ];
              
              Join<Object, Object> item = root.join("item", JoinType.INNER);
              Join<Object, Object> planType = root.join("planType", JoinType.INNER);
              
              if(!StringUtils.isEmpty(itemId)){
                  Predicate p1=criteriaBuilder.equal(item.get("id").as(Long.class), itemId);
                  lstPredicates.add(p1);
              }
              
				if (!StringUtils.isEmpty(planTypeId)) {
					if (code != PlanType.MONTH_TYPE.getCode()) {
						Predicate p1 = criteriaBuilder.equal(planType.get("id").as(Long.class), planTypeId);
						lstPredicates.add(p1);
					}
				}
				if( !"100045".equals(code)) {
	        	  Predicate p2=criteriaBuilder.and(item.in(itemHelper.getCurrentUserItems()));
	              lstPredicates.add(p2);
				}
              return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
	        }
		};
		 List<Plan> findAll = planRepository.findAll(spec);
		return findAll;
	}

	
	
	@Override
	public List<Plan> findPlanByTypeId(Long planTypeId) {
		Specification<Plan> spec = new Specification<Plan> () {  
			/**
			 * 序列号
			 */
			private static final long serialVersionUID = -786003485941679959L;
			@Override
			public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
              List<Predicate> lstPredicates = new ArrayList<Predicate>();
              Predicate[] arrayPredicates = new Predicate[lstPredicates.size() ];
              
              Join<Object, Object> planType = root.join("planType", JoinType.INNER);
              
              if(!StringUtils.isEmpty(planTypeId)){
            	  Predicate p1=criteriaBuilder.equal(planType.get("id").as(Long.class), planTypeId);
            	  lstPredicates.add(p1);
              }

        	  Predicate p1=criteriaBuilder.equal(root.get("state").as(Long.class), "2");
        	  lstPredicates.add(p1);
              return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
	        }
		};
		 List<Plan> findAll = planRepository.findAll(spec);
		return findAll;
	}

	
	@Override
	@Transactional
	public String deletePlan(long id) {
		Plan plan = planService.getById(id);
		List<PlanNode> planNodes = plan.getPlanNodes();
		for(PlanNode planNode : planNodes){
			planNodeService.del(planNode);
		}
		return planService.del(plan);
	}
	
}
